import _ from 'lodash'
import moment from "moment";

function updateValue(objArr, objIdxName, dstObj) {
    for (let obj of objArr) {
        if (obj[objIdxName] === dstObj[objIdxName]) {
            Object.assign(obj, dstObj)
            return obj
        }
    }

    objArr.push(dstObj)
    return dstObj

}

function stripCommonDetailList(modelDetailList) {
    let vModelDict = {}
    for (let model of modelDetailList) {
        let project = model.project_name
        if (project in vModelDict) {
            let vModel = vModelDict[project]
            vModel.model_list.push(model.name)

            let nMakeType = vModel.make_type_list.length
            while (nMakeType--) {
                let makeType = null
                for (let tp of model.make_type_list) {
                    if (tp === vModel.make_type_list[nMakeType]) {
                        makeType = tp
                        break
                    }
                }

                if (makeType === null) {
                    vModel.make_type_list[nMakeType].splice(nMakeType, 1)
                }
            }

            let nRepo = vModel.repos_info.length
            while (nRepo--) {
                let vModelRepo = vModel.repos_info[nRepo]
                let modelRepo = null
                for (let repo of model.repos_info) {
                    // 遍历model的repos_info看看当前的vModel的repo在不在其中
                    if (repo.name === vModelRepo.name) {
                        // 在其中
                        modelRepo = repo
                        break
                    }
                }
                if (modelRepo === null) {
                    // 不在其中，从vModel中删除此repo
                    vModel.repos_info.splice(nRepo, 1)
                } else {
                    // 在其中，继续以同样的方式筛选其他属性: remote_branch ...
                    let nRemote = vModelRepo.remote.length
                    while (nRemote--) {
                        let vModelRepoRemote = vModelRepo.remote[nRemote]
                        let modelRepoRemote = null
                        for (let rmt of modelRepo.remote) {
                            if (rmt.full_name === vModelRepoRemote.full_name) {
                                modelRepoRemote = rmt
                                break
                            }
                        }
                        if (modelRepoRemote === null) {
                            vModelRepo.remote.splice(nRemote, 1)
                        }
                    }
                }
            }

        } else {
            vModelDict[project] = _.cloneDeep(model)
            vModelDict[project].name = project
            vModelDict[project].is_virtual = '1'
            vModelDict[project].model_list = [model.name,] // TODO: put supported real model into it
            let nRepo = vModelDict[project].repos_info.length
            while (nRepo--) {
                vModelDict[project].repos_info[nRepo].current =
                    {
                        'full_name': '',
                        'base_name': '',
                        'commit_id': '',
                        'commit': '',
                    }
            }
            vModelDict[project].default_make_type = ''
        }
    }

    let delList = []
    for (let project in vModelDict) {
        let vModel = vModelDict[project]
        if (vModel.repos_info.length === 0 || vModel.make_type_list.length === 0) {
            delList.push(vModel.name)
        }
    }
    for (let d of delList) {
        delete vModelDict[d]
    }

    return vModelDict
}

// function pushIfNotExist(arr, objIdxName, added) {
//     for (let obj of arr) {
//         if (obj[objIdxName] === added[objIdxName]) {
//             return
//         }
//     }
//
//     arr.push(added)
// }

const state = () => ({
    modelList: [],
    virtualModelList: [],
    selectedModelList: [],
    modelDetailList: [],
    modelSettingList: {},
    modelStateList: [],
    modelFileList: [],
    modelLogList: {},
    modelUploadFileList: [],
    info: '',
    modelState:
        {
            'free':
                {
                    id: '0',
                    description: 'free',
                },
            'pending':
                {
                    id: '1',
                    description: 'Pending',
                },
            'running':
                {
                    id: '2',
                    description: 'Running',
                },
            'failed':
                {
                    id: '3',
                    description: 'Failed',
                },
            'succeed':
                {
                    id: '4',
                    description: 'Succeed',
                },
        },
    makeTypeList:
        [
            {
                id: '1',
                description: 'Make all with core-clean',
            },
            {
                id: '2',
                description: 'Only make core',
            },
            {
                id: '3',
                description: 'Only make mib files',
            },
            {
                id: '4',
                description: 'Only make all',
            },
            {
                id: '5',
                description: 'Make all with all-clean',
            },
        ]
})

const getters = {
    getBugFixedByModel: (state) => (model) => {
        return state.modelSettingList[model]['release_info']['bug_fixed']
    }
}


const actions = {}

const mutations = {
    updateInfo(state, info) {
        state.info += info += '\r\n'
    },

    removeVirtualModels(state, vModelName) {
        let len = state.modelDetailList.length
        while (len--) {
            let modelDetail = state.modelDetailList[len]
            if (modelDetail.is_virtual === '1') {
                if (vModelName !== undefined && vModelName !== modelDetail.name) {
                    continue
                }
                state.modelDetailList.splice(len, 1)
            }
        }
        let sLen = state.modelSettingList.length
        while (sLen--) {
            let modelSetting = state.modelSettingList[sLen]
            if (state.modelSettingList[sLen].is_virtual === '1') {
                if (vModelName !== undefined && vModelName !== modelSetting.name) {
                    continue
                }
                state.modelSettingList.splice(sLen, 1)
            }
        }
        if (vModelName !== undefined) {
            let vLen = state.virtualModelList.length
            while (vLen--) {
                if (state.virtualModelList[vLen].name === vModelName) {
                    state.virtualModelList.splice(vLen, 1)
                    break
                }
            }
        } else {
            state.virtualModelList = []
        }
    },

    updateVirtualModels(state, {vModelName, modelList}) {
        // now we should strip global info from them for global setting .
        let detailList = []

        if (modelList === undefined || modelList.length === 0) {
            if (vModelName === undefined || vModelName.length === 0) {
                detailList = state.modelDetailList
            } else {
                for (let modelDetail of state.modelDetailList) {
                    if (modelDetail.project_name === vModelName) {
                        detailList.push(modelDetail)
                    }
                }
            }
        } else {
            for (let model of modelList) {
                for (let d of state.modelDetailList) {
                    if (d.name === model) {
                        detailList.push(d)
                        break
                    }
                }
            }
        }
        let vModelDict = stripCommonDetailList(detailList)
        for (let m in vModelDict) {
            let vModel = vModelDict[m]
            state.modelDetailList.push(vModel)
            state.virtualModelList.push(vModel)

            state.modelSettingList[vModel.name] = {
                model_name: vModel.name,
                make_type: vModel.default_make_type,
                repos_info: {},
                release_info: {
                    bug_fixed: '',
                    new_feature: '',
                    changed: '',
                    note: '',
                    known_issue: '',
                },
                is_virtual: '1'
            }
        }
    },

    removeModelDetailList(state, modelList) {
        let len = state.modelDetailList.length
        while (len--) {
            if (state.modelDetailList[len].name in modelList) {
                state.modelDetailList.splice(len, 1)
            }
        }
    },

    syncVirtualSettingsToReal(state) {
        for (let vm of state.virtualModelList) {
            let vmSetting = {}
            let modelList = vm.model_list
            for (let mName in state.modelSettingList) {
                if (vm.name === mName) {
                    vmSetting = state.modelSettingList[mName]
                    break
                }
            }

            for (let mName in state.modelSettingList) {
                let m = state.modelSettingList[mName]
                if (modelList.indexOf(mName) >= 0) {
                    if (vmSetting.make_type !== '') {
                        m.make_type = vmSetting.make_type
                    }
                    if (vmSetting.release_info.bug_fixed !== '') {
                        m.release_info.bug_fixed = vmSetting.release_info.bug_fixed
                    }
                    if (vmSetting.release_info.new_feature !== '') {
                        m.release_info.new_feature = vmSetting.release_info.new_feature
                    }
                    if (vmSetting.release_info.changed !== '') {
                        m.release_info.changed = vmSetting.release_info.changed
                    }
                    if (vmSetting.release_info.known_issue !== '') {
                        m.release_info.known_issue = vmSetting.release_info.known_issue
                    }
                    if (vmSetting.release_info.note !== '') {
                        m.release_info.note = vmSetting.release_info.note
                    }
                    if (Object.keys(vmSetting.repos_info).length !== 0) {
                        Object.assign(m.repos_info, vmSetting.repos_info)
                    }
                }
            }
        }
    },

    setModelDetailList(state, modelDetailList) {
        state.modelDetailList = modelDetailList
    },

    setModelList(state, modelList) {
        state.modelList = modelList
    },

    resetModelStateList(state) {
        state.modelStateList = []
    },

    setModelState(state, modelState) {
        let modelIdx = state.modelStateList.findIndex((m) => {
            return m.name === modelState.name
        })
        let ms = null
        if (modelIdx < 0) {
            ms = updateValue(state.modelStateList,
                'name',
                {
                    name: modelState.name,
                    state: modelState.state,
                    sTime: modelState.start_time,
                    elapsed: '————',
                    timerId: null,
                    timer: function () {
                        this.timerId = window.setInterval(() => {
                            this.elapsed++
                        }, 1000)
                    }
                }
            )
        }  else {
            ms = state.modelStateList[modelIdx]
        }
        console.log(ms)
        if (modelState.state !== state.modelState.free.id
            && modelState.state !== '') {

            ms.sTime = modelState.start_time
        }
        if (modelState.state !== state.modelState.free.id
            && modelState.state !== state.modelState.pending.id) {
            ms.state = modelState.state
        }
        if (modelState.state === state.modelState.running.id) {
            let now = moment()
            console.log('\r\n###############################\r\n')
            console.log(now)
            console.log(ms.sTime)
            ms.elapsed = now.diff(
                moment(ms.sTime, 'YYYY-MM-DD hh:mm:ss'),
                'seconds'
            )
            console.log(ms.elapsed)
            console.log('\r\n###############################\r\n')
            ms.timer()
        } else if (modelState.state === state.modelState.succeed.id) {
            ms.elapsed = modelState.elapsed
            updateValue(
                state.modelFileList,
                'name',
                {
                    'name': modelState.name,
                    'files': modelState.files,
                }
            )
        } else if (modelState.state === state.modelState.failed.id) {
            state.modelLogList[modelState.name] = modelState.log
        }
        if (modelState.state !== state.modelState.running.id
            && modelState.state !== state.modelState.free.id) {
            window.clearInterval(ms.timerId)
        }
    },

    setSelectedModelList(state, selModelList) {
        state.selectedModelList = selModelList
    },

    initModelStateList(state, {modelList, initState}) {
        for (let model of modelList) {
            updateValue(state.modelStateList,
                'name',
                {
                    name: model,
                    state: initState,
                    sTime: '———',
                    elapsed: '———',
                    timerId: null,
                    timer: function () {
                        this.timerId = window.setInterval(() => {
                            this.elapsed++
                        }, 1000)
                    }
                }
            )
        }
    },

    initModelSettingList(state, modelList) {
        for (let model of modelList) {
            state.modelSettingList[model] = {
                model_name: model,
                make_type: state.makeTypeList[0]['id'],
                repos_info: {},
                release_info: {
                    bug_fixed: 'N/A',
                    new_feature: 'N/A',
                    changed: 'N/A',
                    note: 'N/A',
                    known_issue: 'N/A',
                    is_virtual: '0'
                }
            }
        }
    },

    resetModelSettingList(state, modelList) {
        for (let model of modelList) {
            delete state.modelSettingList[model]
        }
    },

    resetBranch(state, br) {
        delete state.modelSettingList[br.model].repos_info[br.repo]
    },

    updateBranch(state, br) {
        for (let repo in state.modelSettingList[br.model].repos_info) {
            if (repo === br.repo) {
                state.modelSettingList[br.model].repos_info[repo] = br.repo
                return
            }
        }
        state.modelSettingList[br.model].repos_info[br.repo] = br.branch
    },

    updateBugFixed(state, {model, bugFixed}) {
        state.modelSettingList[model].release_info.bug_fixed = bugFixed
    },

    updateNewFeature(state, {model, newFeature}) {
        state.modelSettingList[model].release_info.new_feature = newFeature
    },

    updateChanged(state, {model, changed}) {
        state.modelSettingList[model].release_info.changed = changed
    },

    updateNote(state, {model, note}) {
        state.modelSettingList[model].release_info.note = note
    },

    updateKnownIssue(state, {model, knownIssue}) {
        state.modelSettingList[model].release_info.known_issue = knownIssue
    },

    updateMakeType(state, {model, makeType}) {
        state.modelSettingList[model].make_type = makeType
    },

    setUploadFileList(state, fileList) {
        state.modelUploadFileList = fileList
    }
}

export default {
    namespace: false,
    state,
    getters,
    actions,
    mutations
}
